
#include "lib_jpeg.h"

#define  MAX_IMAGE_W      	  (8192)
#define  MAX_IMAGE_H     	  (8192)
#define  MAX_IMAGE_BPP        (3)

#if 0
#define  DST_IMAGE_W      	  (3840)
#define  DST_IMAGE_H     	  (2160)
#elif 0
#define  DST_IMAGE_W      	  (1920)
#define  DST_IMAGE_H     	  (1080)
#elif 1
#define  DST_IMAGE_W      	  (2560)
#define  DST_IMAGE_H     	  (1440)
#endif
#define  DST_IMAGE_BPP        (3)
//*******************************************************************************

#define CODEC_ALIGN(x, a)   (((x)+(a)-1)&~((a)-1))
//*******************************************************************************

static  char * image_src_buff  	  = NULL;
static  char * image_dst_buff     = NULL;
static  char * image_show_buff    = NULL;
//*******************************************************************************
int is_jpeg_file_t(char *filename,jpeg_file_t *pfd)
{
	int ret;
	uint32_t word;

    pfd->cinfo.err = jpeg_std_error(&pfd->jerr);
	//创建一个jpeg_compress_struct结构体
    jpeg_create_decompress(&pfd->cinfo);
	
	//指定jpeg解压的源文件
    jpeg_stdio_src(&pfd->cinfo, pfd->fp);
	
	//解析jpeg文件，解析完成后可获得图像的格式
    ret = jpeg_read_header(&pfd->cinfo, TRUE);
	if(ret < 0){
		log_e("file is not jpg ...\n");
		return -1;
	}

	return 0;
}


void free_jpeg(jpeg_file_t *jf)
{
	if(jf->buffer)
	{
		free(jf->buffer);
	}

	jf->buffer = NULL;
}



int decode_jpeg(char *filename,jpeg_file_t *jf)
{
	int ret;
	uint32_t word;
	unsigned char *buf_cpy;
	//临时变量行buffer
	uint8_t *pucbuffer;
	
	//放大倍率
	jf->cinfo.scale_num = 1;//2
	//缩小倍率
	jf->cinfo.scale_denom = 1;

	//jf->cinfo.out_color_space = JCS_RGB;

	//对cinfo所指定的源文件进行解压，并将解压后的数据存到cinfo结构体的成员变量中。
    jpeg_start_decompress(&jf->cinfo);
	//获取图片基本信息
    jf->row_size = jf->cinfo.output_width * jf->cinfo.output_components;
    jf->width = jf->cinfo.output_width;
    jf->height = jf->cinfo.output_height;
	jf->Bpp = jf->cinfo.output_components;
    jf->size = jf->row_size * jf->cinfo.output_height;
	
	//分配内存空间 
	pucbuffer = malloc(jf->row_size);
    jf->buffer = malloc(jf->size);

#if 0

	log_i("jpeg_color_space=%d\n",jf->cinfo.jpeg_color_space);

    printf("size: %d w: %d h: %d row_size: %d ,Bpp: %d\n",
			jf->size,jf->width,jf->height,jf->row_size,jf->Bpp);
#endif
			
	//缓冲指针指向buffer		
	buf_cpy = jf->buffer;

    while (jf->cinfo.output_scanline < jf->cinfo.output_height){
        //可以读取RGB数据到buffer中，参数3能指定读取多少行
		jpeg_read_scanlines(&jf->cinfo, &pucbuffer, 1);
        //复制到内存
		memcpy(buf_cpy , pucbuffer, jf->row_size);
		buf_cpy = buf_cpy + jf->row_size;
    }

	// 完成解码
	jpeg_finish_decompress(&jf->cinfo);
	free(pucbuffer);
	//释放结构体
    jpeg_destroy_decompress(&jf->cinfo);

	return 0;
}

int decode_jpg_show_equal(char *filename)
{
	int ret;

	int i = 0;
	int j = 0;
	
	int dst_w = 0;
	int dst_h = 0;

	int src_w = 0;
	int src_h = 0;

	int lcd_w = 0;
	int lcd_h = 0;

	int v_w = 0;
	int v_h = 0;

	int bpp   = 0;
	
	int s_x = 0;
	int s_y = 0;
		
	jpeg_file_t jf;
	//**************************************************

	jf.fp= fopen(filename, "rb");
	if (jf.fp== NULL) {
		log_e("can not open file,%s\n",filename);
		return -1;
	}
	
	memset(jf.filename,0,sizeof(jf.filename));
	memcpy(jf.filename,filename,strlen(filename));

	ret =is_jpeg_file_t(filename,&jf);
	if(ret < 0 ){
		log_e("not jpeg file");
    	fclose(jf.fp);
		return -1;
	}

	ret = decode_jpeg(filename,&jf);
	if(ret < 0 ){
		log_e("decode jpeg wrong\n");
		fclose(jf.fp);
		return -1;
	}
	//***********************************************************************************************
	//***********************************************************************************************
	memset(image_src_buff,0,MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	memset(image_dst_buff,0,MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	memset(image_show_buff,0,DST_IMAGE_W*DST_IMAGE_H*DST_IMAGE_BPP);
	//***********************************************************************************************
	lcd_w = lib_drm_get_hdmi_w();
	lcd_h = lib_drm_get_hdmi_h();

	src_w = jf.width;
	src_h = jf.height;
	bpp   = jf.Bpp;
	
	log_n("lcd_w:h=%d:%d\n",lcd_w,lcd_h);
	log_n("pic_w:h:b=%d:%d:%d\n",jf.width,jf.height,jf.Bpp);
	//***********************************************************************************************

	v_w   = 1920;
	v_h   = 1080;
	//***********************************************************************************************
	if((src_w >= v_w)&&(src_h >= v_h))
	{
		dst_w = lcd_w;
		dst_h = lcd_h;
	}
	else if((src_w >= v_w)&&(src_h < v_h))
	{	
		dst_w = lcd_w;
		dst_h = (src_h*lcd_w)/src_w;
	}
	else if((src_w < v_w)&&(src_h >= v_h))
	{
		dst_w = (src_w*lcd_h)/src_h;
		dst_h = lcd_h;
	}
	else 
	{
		dst_w = src_w;
		dst_h = src_h;
	}
	//***********************************************************************************************
	src_w  = CODEC_ALIGN(jf.width, 4);
    src_h  = CODEC_ALIGN(jf.height,4);
	dst_w  = CODEC_ALIGN(dst_w,4);
    dst_h  = CODEC_ALIGN(dst_h,4);
	//***********************************************************************************************

	log_n("dst_w:h=%d:%d\n",dst_w,dst_h);
	//***********************************************************************************************
	for(i = 0;i < jf.height;i++)
	{
		memcpy(image_src_buff + i*src_w*bpp,jf.buffer + i*jf.width*bpp ,jf.width*bpp);	
	}
	//***********************************************************************************************
	ret = rga_rgbdata_resize_hdmi(image_src_buff,src_w,src_h,bpp,
							      image_dst_buff,dst_w,dst_h,bpp);
	if(ret < 0){
		fclose(jf.fp);
		free_jpeg(&jf);
		return ret;
	}
	//***********************************************************************************************
	s_x = (DST_IMAGE_W - dst_w)/2;
	s_y = (DST_IMAGE_H - dst_h)/2;
		
	log_n("show_x:y =%d:%d\n",s_x,s_y);
	//***********************************************************************************************
	for(i=0;i<DST_IMAGE_H;i++)
	{	
		if((i >= s_y)&&(i < (s_y + dst_h)))
		{
			memcpy(image_show_buff + i*DST_IMAGE_W*bpp + s_x*bpp,
				    image_dst_buff + (i-s_y)*dst_w*bpp,dst_w*bpp);
		}
	}
	//***********************************************************************************************

	dst_w = DST_IMAGE_W;
	dst_h = DST_IMAGE_H;
	ret = lib_drm_hdmi_nv12_show(image_show_buff,dst_w,dst_h,dst_w*dst_h*bpp);
	//***********************************************************************************************
	
	fclose(jf.fp);
	free_jpeg(&jf);
	//***********************************************************************************************
	
	return ret;

}

int decode_jpg_show_cut(char *filename)
{
	int ret;

	int i = 0;
	int j = 0;
	
	int dst_w = 0;
	int dst_h = 0;

	int src_w = 0;
	int src_h = 0;
	int src_b = 0;

	int lcd_w = 0;
	int lcd_h = 0;

	int cop_w = 0;
	int cop_h = 0;
	int cop_x = 0;
	int cop_y = 0;

	
	int s_x = 0;
	int s_y = 0;

	float d_scale = 0.0;
	float s_scale = 0.0;
		
	jpeg_file_t jf;
	//**************************************************

	jf.fp= fopen(filename, "rb");
	if (jf.fp== NULL) {
		log_e("can not open file,%s\n",filename);
		return -1;
	}
	
	memset(jf.filename,0,sizeof(jf.filename));
	memcpy(jf.filename,filename,strlen(filename));

	ret =is_jpeg_file_t(filename,&jf);
	if(ret < 0 ){
		log_e("not jpeg file");
    	fclose(jf.fp);
		return -1;
	}

	ret = decode_jpeg(filename,&jf);
	if(ret < 0 ){
		log_e("decode jpeg wrong\n");
		fclose(jf.fp);
		return -1;
	}
	//***********************************************************************************************
	log_n("pic_w:h:b=%d:%d:%d\n",jf.width,jf.height,jf.Bpp);
	//***********************************************************************************************
	memset(image_src_buff,0,MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	memset(image_dst_buff,0,MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	memset(image_show_buff,0,DST_IMAGE_W*DST_IMAGE_H*DST_IMAGE_BPP);
	//***********************************************************************************************
	lcd_w = lib_drm_get_hdmi_w();
	lcd_h = lib_drm_get_hdmi_h();

	src_w = jf.width;
	src_h = jf.height;
	src_b = jf.Bpp;

	d_scale = (float)lcd_w/(float)lcd_h;
	s_scale = (float)src_w/(float)src_h;

	log_n("lcd_w:h=%d:%d\n",lcd_w,lcd_h);
	log_n("d_sca=%f\n",d_scale);
	log_n("s_sca=%f\n",s_scale);
	//***********************************************************************************************
	if(s_scale > d_scale)
	{
		cop_w = src_h*d_scale;	
		cop_h = src_h;
	}
	else
	{
		cop_w = src_w;	
		cop_h = src_w/d_scale;
	}
	//***********************************************************************************************
	dst_w = lcd_w;
	dst_h = lcd_h;
	//***********************************************************************************************
	dst_w  = CODEC_ALIGN(dst_w,4);
    dst_h  = CODEC_ALIGN(dst_h,4);	
	cop_w  = CODEC_ALIGN(cop_w,4);
    cop_h  = CODEC_ALIGN(cop_h,4);

	if(cop_w > src_w)
	{
		cop_w = cop_w - 4;
	}	
	if(cop_h > src_h)
	{
		cop_h = cop_h- 4;
	}
	//***********************************************************************************************
	cop_x = (src_w - cop_w)/2;
	cop_y = (src_h - cop_h)*35/100;
	//***********************************************************************************************
	log_n("src_w:h =%d:%d\n",src_w,src_h);
	log_n("cop_w:h =%d:%d\n",cop_w,cop_h);
	log_n("cop_x:y =%d:%d\n",cop_x,cop_y);
	log_n("dst_w:h =%d:%d\n",dst_w,dst_h);
	//***********************************************************************************************
	for(i=0;i<src_h;i++)
	{	
		if((i >= cop_y)&&(i < (cop_y + cop_h)))
		{
			memcpy(image_src_buff + (i-cop_y)*cop_w*src_b,
				    jf.buffer     + (i-0    )*src_w*src_b + cop_x*src_b,cop_w*src_b);
		}
	}
	//***********************************************************************************************
	ret = rga_rgbdata_resize_hdmi(image_src_buff,cop_w,cop_h,src_b,
							      image_dst_buff,dst_w,dst_h,src_b);
	if(ret < 0){
		fclose(jf.fp);
		free_jpeg(&jf);
		return ret;
	}
	//***********************************************************************************************
	s_x = (DST_IMAGE_W - dst_w)/2;
	s_y = (DST_IMAGE_H - dst_h)/2;
		
	log_n("show_x =%d\n",s_x);
	log_n("show_y =%d\n",s_y);
	//***********************************************************************************************
	for(i=0;i<DST_IMAGE_H;i++)
	{	
		if((i >= s_y)&&(i < (s_y + dst_h)))
		{
			memcpy(image_show_buff + i*DST_IMAGE_W*src_b + s_x*src_b,
				    image_dst_buff + (i-s_y)*dst_w*src_b,dst_w*src_b);
		}
	}
	//***********************************************************************************************

	dst_w = DST_IMAGE_W;
	dst_h = DST_IMAGE_H;
	ret = lib_drm_hdmi_nv12_show(image_show_buff,dst_w,dst_h,dst_w*dst_h*src_b);
	//***********************************************************************************************
	
	fclose(jf.fp);
	free_jpeg(&jf);
	//***********************************************************************************************
	
	return ret;

}


int lib_jpeg_init(void)
{
	unsigned long max_address = 0xfffffffe; // 4GB

	log_n("lib jpeg init.\n");
	
	log_n("max_address=%x\n",max_address);
	//************************************************************
	//max 4G 
	image_src_buff = malloc(MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);	
	if((image_src_buff == NULL)||(image_src_buff < max_address))
	{
		exit(-1);
	}
	//************************************************************
	image_dst_buff = malloc(MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	if((image_dst_buff == NULL)||(image_dst_buff < max_address))
	{
		exit(-1);
	}
	//************************************************************
	image_show_buff = malloc(DST_IMAGE_W*DST_IMAGE_H*DST_IMAGE_BPP);
	if(image_show_buff == NULL)
	{
		exit(-1);
	}
	//************************************************************


	return 0;
}


int lib_jpeg_deinit(void)
{
	log_i("lib jpeg exit.\n");






	return 0;
}
